package global

import (
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
	"lib/db"
	"lib/structs/tables"
)

func InitDB() {
	var err error
	DB, err = db.GetDB(Conf.DB.Supper, Conf.DB.ShowSqlLog, Conf.DB.Source, Conf.AppFolder)
	if err != nil {
		logrus.Panicf("连接数据库失败：%v", err)
	}
	autoMigrate()
}
func autoMigrate() {
	type vector[T any] []T
	var li = vector[interface{}]{
		&tables.User{},
		&tables.UserExtend{},
		&tables.Role{},
		&tables.MapUserRole{},
		&tables.Org{},
		&tables.MapUserOrg{},
	}
	for _, item := range li {
		if !DB.Migrator().HasTable(item) {
			err := DB.AutoMigrate(item)
			if err != nil {
				logrus.Errorf("初始化数据库表结构异常: %v", err)
			}
		}
	}
	initUser()
	initRole()
	initUserMapRole()
	initOrg()
}

func initUser() {
	var err error
	var rootUser = &tables.User{
		UserId:    1,
		Username:  "root",
		Password:  "3.14",
		OrgId:     tables.DefaultRootOrgId,
		Status:    1,
		IsOnline:  2,
		AccountLv: 1,
		Extend: tables.UserExtend{
			Id:       1,
			UserId:   1,
			Nickname: "root",
			Email:    "337815986@qq.com",
			CityCode: "420000",
		},
	}
	var d tables.User
	if err = DB.Where("user_id = 1").First(&d).Error; errors.Is(err, gorm.ErrRecordNotFound) {
		rootUser.Creator, rootUser.CreatorId = "root", 1
		err = DB.Create(rootUser).Error
		if err != nil {
			panic(fmt.Sprintf("导入初始化用户信息时发生错误：%v", err))
		}
		mut := tables.UserExtend{
			UserId: 1,
		}
		err = DB.Create(&mut).Error
		if err != nil {
			panic(fmt.Sprintf("导入初始化sql信息时发生错误：%v", err))
		}
	}
}

func initRole() {
	var err error
	defaultRole := []tables.Role{
		{
			RoleId:   1,
			RoleName: "超级管理员",
			RoleCode: "sys",
			RoleDesc: "系统内置的超级管理角色",
			IsSys:    1,
			IsOpen:   1,
			AutoCreateInfo: tables.AutoCreateInfo{
				Creator:   "root",
				CreatorId: 1,
			},
		},
		{
			RoleId:   2,
			RoleName: "管理员",
			RoleCode: "admin",
			RoleDesc: "系统内置的管理角色",
			IsSys:    1,
			IsOpen:   1,
			AutoCreateInfo: tables.AutoCreateInfo{
				Creator:   "root",
				CreatorId: 1,
			},
		},
		{
			RoleId:   3,
			RoleName: "用户",
			RoleCode: "user",
			RoleDesc: "系统内置的用户角色",
			IsSys:    1,
			IsOpen:   1,
			AutoCreateInfo: tables.AutoCreateInfo{
				Creator:   "root",
				CreatorId: 1,
			},
		},
	}

	var t int64
	if err = DB.Where("role_id = in (1,2,3)").Count(&t).Error; err != nil || t != 3 {
		err = DB.Save(&defaultRole).Error
		if err != nil {
			panic(fmt.Sprintf("导入初始化角色信息时发生错误：%v", err))
		}
	}
}

func initUserMapRole() {
	var err error
	mus := tables.MapUserRole{
		UserId: 1,
		RoleId: 1,
	}
	var d tables.MapUserRole
	if err = DB.Model(&tables.MapUserRole{}).Where("user_id = ? and role_id = ?", mus.UserId, mus.RoleId).First(&d).Error; errors.Is(err, gorm.ErrRecordNotFound) {
		err = DB.Create(&mus).Error
		if err != nil {
			panic(fmt.Sprintf("导入初始化sql信息时发生错误：%v", err))
		}
	}
}

func initOrg() {
	t1 := tables.Org{
		Id:       tables.DefaultRootOrgId,
		ParentId: 0,
		OrgName:  "全部",
		Status:   1,
		AutoCreateInfo: tables.AutoCreateInfo{
			Creator:   "root",
			CreatorId: tables.RootId,
		},
	}
	t2 := tables.Org{
		Id:       tables.DefaultNothingOrgId,
		ParentId: 0,
		OrgName:  "未分配",
		Status:   1,
		AutoCreateInfo: tables.AutoCreateInfo{
			Creator:   "root",
			CreatorId: tables.RootId,
		},
	}
	var num int64
	err := DB.Model(&tables.Org{}).Where("id in ?", []int64{tables.DefaultRootOrgId, tables.DefaultNothingOrgId}).Count(&num).Error
	if err != nil {
		panic(fmt.Sprintf("导入初始化sql信息时发生错误：%v", err))
	}
	if num == 0 {
		li := make([]tables.Org, 0)
		li = append(li, t1, t2)
		err = DB.CreateInBatches(&li, len(li)).Error
		if err != nil {
			panic(fmt.Sprintf("导入初始化sql信息时发生错误：%v", err))
		}
	}
	if DB.Model(&tables.MapUserOrg{}).Where(&tables.MapUserOrg{OrgId: tables.RootId}).Count(&num).Error != nil {
		panic(fmt.Sprintf("导入初始化sql信息时发生错误：%v", err))
	}
	if num == 0 {
		m1 := tables.MapUserOrg{
			UserId: tables.RootId,
			OrgId:  tables.DefaultRootOrgId,
		}
		m2 := tables.MapUserOrg{
			UserId: tables.RootId,
			OrgId:  tables.DefaultNothingOrgId,
		}
		li := make([]tables.MapUserOrg, 0)
		li = append(li, m1, m2)
		if DB.CreateInBatches(&li, len(li)).Error != nil {
			panic(fmt.Sprintf("导入初始化sql信息时发生错误：%v", err))
		}
	}

}
